/*!
 * \file depth_first_visitor_adapter.h
 *
 * \brief Declarations for the depth first visitor adapter for the AST
 *
 * \date Started: 5/17/2010
 * \date Last Modified: 7/27/2010
 * \authors Ian Craig
 */

#ifndef DFVA_H
#define DFVA_H

#include <iegenlib/iegenlib.h>

namespace iegenlib{

/*!
 * \class DepthFirstVisitorAdapter
 *
 * \brief A base visitor that performs a depth-first traversal
 *
 * This class serves as a base for a depth-first traversal through the AST.
 * Essentially the case methods implement the depth-first traversal and
 * call the in and out methods for a node before and after the children
 * of the node are visited.
 * The in and out methods should be overloaded depending on what you
 * are trying to accomplish with the visitor.
 *
 * OF SPECIAL NOTE: If you are overloading a case function, this will undo the
 * actual calls to that respective nodes' in and out method calls.
 */
class DepthFirstVisitorAdapter:public VisitorAdapter{
public:

  DepthFirstVisitorAdapter(){}
  virtual ~DepthFirstVisitorAdapter(){}

  /*!
   * Used for general tasks to be done going into every visited node
   * @param node ast node to do tasks on
   */
  virtual void defaultIn(Node* node) = 0;

  /*!
   * Used for general tasks to be done going out of every visited node
   * @param node ast node to do tasks on
   */
  virtual void defaultOut(Node* node) = 0;

  /*!
   * hook method called by the nodeCase method before any
   * of the node's children are visited
   * @param node ast node being visited that is called
   */
/*
MMS, we shouldn't need these more general in, case, and out methods.
  virtual void nodeIn(Node* node) = 0;

  virtual inline void nodeIn(Node* node){defaultIn(node);}

  virtual inline void nodeCase(Node* node){nodeIn(node); nodeOut(node);}
  virtual inline void nodeOut(Node* node){defaultOut(node);}
*/


  virtual inline void PresFormIn(PresForm* node){defaultIn(node);}
  virtual inline void PresFormCase(PresForm* node){PresFormIn(node); PresFormOut(node);}
  virtual inline void PresFormOut(PresForm* node){defaultOut(node);}

  virtual inline void PresSetIn(PresSet* node){defaultIn(node);}
  virtual void PresSetCase(PresSet* node);
  virtual inline void PresSetOut(PresSet* node){defaultOut(node);}

  virtual inline void PresRelationIn(PresRelation* node){defaultIn(node);}
  virtual void PresRelationCase(PresRelation* node);
  virtual inline void PresRelationOut(PresRelation* node){defaultOut(node);}

  virtual inline void VarTupleIn(VarTuple* node){defaultIn(node);}
  virtual void VarTupleCase(VarTuple* node);
  virtual inline void VarTupleOut(VarTuple* node){defaultOut(node);}

  virtual inline void ConjunctionIn(Conjunction* node){defaultIn(node);}
  virtual void ConjunctionCase(Conjunction* node);
  virtual inline void ConjunctionOut(Conjunction* node){defaultOut(node);}

  virtual inline void ConstraintIn(Constraint* node){defaultIn(node);}
  virtual inline void ConstraintCase(Constraint* node){ConstraintIn(node); ConstraintOut(node);}
  virtual inline void ConstraintOut(Constraint* node){defaultOut(node);}

  virtual inline void EqualityIn(Equality* node){defaultIn(node);}
  virtual void EqualityCase(Equality* node);
  virtual inline void EqualityOut(Equality* node){defaultOut(node);}

  virtual inline void InequalityIn(Inequality* node){defaultIn(node);}
  virtual void InequalityCase(Inequality* node);
  virtual inline void InequalityOut(Inequality* node){defaultOut(node);}

  virtual inline void ExpressionIn(Expression* node){defaultIn(node);}
  virtual inline void ExpressionCase(Expression* node){ExpressionIn(node); ExpressionOut(node);}
  virtual inline void ExpressionOut(Expression* node){defaultOut(node);}

  virtual inline void VarExpIn(VarExp* node){defaultIn(node);}
  virtual inline void VarExpCase(VarExp* node){VarExpIn(node); VarExpOut(node);}
  virtual inline void VarExpOut(VarExp* node){defaultOut(node);}

  virtual inline void FuncExpIn(FuncExp* node){defaultIn(node);}
  virtual void FuncExpCase(FuncExp* node);
  virtual inline void FuncExpOut(FuncExp* node){defaultOut(node);}

  virtual inline void NormExpIn(NormExp* node){defaultIn(node);}
  virtual void NormExpCase(NormExp* node);
  virtual inline void NormExpOut(NormExp* node){defaultOut(node);}

};

}//end namespace iegenlib

#endif
